package dcsinstnce.server.interfaces.impl;

import java.util.Vector;
import dcsinstnce.server.accessers.impl.DataReaderImpl;
import dcsinstnce.server.interfaces.SuscriberManagerOperations;

/**
 * 
 * @author doumbouya
 *
 */
public class SuscriberManagerImpl implements SuscriberManagerOperations {
	public static int MAX_TOPIC_BY_SUSCRIBER = 4;
	private Vector<SuscriberImpl> suscribers = null;
	/**
	 * constructeur
	 */
	public SuscriberManagerImpl() {
		suscribers = new Vector<SuscriberImpl>();
	}

	/**
	 * return : le nombre de subscriber
	 */
	@Override
	public short getSuscriberCount() {
		return (short) suscribers.size();
	}

	/**
	 * 
	 * @return : le vecteur de subscriber
	 */
	public Vector<SuscriberImpl> getSuscribers() {
		return suscribers;
	}

	/**
	 * 
	 * @param topicName : le nom du topic devant être ajouté
	 * @param listener : son listener correspondant
	 * @return : le subscriber qui le prendra en charge
	 */
	public SuscriberImpl addNewDataReaderListener(String topicName,
			DataReaderImpl listener) {
		SuscriberImpl eligibleSuscriber = getEligibleSuscriber();
		eligibleSuscriber.addDataReaderListener(topicName, listener);
		return eligibleSuscriber;
	}

	/**
	 * 
	 * @return : le subscriber apte à prendre en charge le nouveau listener : le moyen charger
	 */
	private SuscriberImpl getEligibleSuscriber() {
		int nbSuscriber = -1, suscriberCount = -1, posSuscriber = -1;
		for (int i = 0; i < suscribers.size(); i++) {
			suscriberCount = (int) suscribers.get(i).getListenerCount();
			if (i == 0) {
				nbSuscriber = suscriberCount;
				posSuscriber = 0;
			}
			if (suscriberCount < nbSuscriber) {
				posSuscriber = i;
				nbSuscriber = suscriberCount;
			}
		}
		if (posSuscriber == -1 || nbSuscriber > MAX_TOPIC_BY_SUSCRIBER) {
			return addNewSuscriber();
		}
		return suscribers.get(posSuscriber);
	}

	/**
	 * 
	 * @return : le nouveau subscriber creer
	 */
	private SuscriberImpl addNewSuscriber() {
		int nbForCopi = (int) (MAX_TOPIC_BY_SUSCRIBER / (suscribers.size() + 1));
		int nbLimit;
		SuscriberImpl end_suscriber = new SuscriberImpl(), temp_suscriber = null;
		for (int i = 0; i < suscribers.size(); i++) {
			temp_suscriber = suscribers.get(i);
			nbLimit = temp_suscriber.getListenerCount() - nbForCopi;
			for (int j = temp_suscriber.getListenerCount() - 1; j >= nbLimit; j--) {
				end_suscriber.addDataReaderListener(
						temp_suscriber.getDataReaderListenerName((short) j),
						temp_suscriber.getDataReaderListener1((short) j));

				temp_suscriber.removeListener(j);
			}
		}
		suscribers.add(end_suscriber);
		return end_suscriber;
	}

}
